/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package lineage.controller.pc;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import lineage.controller.L1AccountController;
import lineage.core.L1GameClient;
import lineage.database.tables.CharactersTable;
import lineage.database.tables.ExpTable;
import lineage.model.instance.L1PcInstance;

/**
 * 角色控制器.
 * 
 * @version 2014年3月19日下午10:38:23
 * @author jrwz
 */
public final class L1PcController {
    private L1PcController() {
    }

    /**
     * 增加新角色(数据库+缓存内).
     * <p>
     * 同时也会更新以下项：<br>
     * 1.帐号资料表内角色数量+1
     * 
     * @param client
     *            - 客户端对象
     * @param pc
     *            - 要增加的角色
     * @return 如果增加成功则返回true
     */
    public static final boolean addCharacters(final L1GameClient client, final L1PcInstance pc) {
        boolean flag = false;
        flag = CharactersTable.getInstance().addCharacters(pc);
        if (flag) {
            final int count = client.getAccount().getCharCount(); // L1AccountController.getInstance().getCharCount(client.getAccountName());
            L1AccountController.getInstance().updateCharCount(client, count + 1);
        }
        return flag;
    }

    /**
     * 删除角色(数据库+缓存内).
     * <p>
     * 同时也会更新以下项：<br>
     * 1.帐号资料表内角色数量-1
     * 
     * @param client
     *            - 客户端对象
     * @param pc
     *            - 要删除的角色
     * @return 如果删除成功则返回true
     */
    public static final boolean delCharacters(final L1GameClient client, final L1PcInstance pc) {
        boolean flag = false;
        flag = CharactersTable.getInstance().delCharacters(pc);
        if (flag) {
            final int count = client.getAccount().getCharCount(); // L1AccountController.getInstance().getCharCount(client.getAccountName());
            L1AccountController.getInstance().updateCharCount(client, count - 1); // 更新角色数量
        }
        return flag;
    }

    /**
     * 更新角色删除时间 - 从当前时间算起7天之后(数据库内).
     * 
     * @param pc
     *            - 要更新的角色
     * @return 如果成功更改则返回true
     */
    public static final boolean updateDelTime(final L1PcInstance pc) {
        return CharactersTable.getInstance().updateDelTime(pc);
    }

    /**
     * 检查是否已经有此角色名称.
     * 
     * @param name
     *            - 要检查的名称
     * @return 有则返回true
     */
    public static final boolean isName(final String name) {
        return CharactersTable.getInstance().isName(name);
    }

    /**
     * 将角色的资料储存进数据库.
     * 
     * @param pc
     *            - 要储存的角色
     * @return 如果储存成功则返回true
     */
    public static final boolean storeCharacter(final L1PcInstance pc) {
        synchronized (pc) {
            return CharactersTable.getInstance().storeCharacter(pc);
        }
    }

    /**
     * 根据角色名取得L1PcInstance对象.
     * 
     * @param name
     *            - 角色名
     * @return L1PcInstance对象(如果找不到则返回null)
     */
    public static final L1PcInstance getPc(final String name) {
        return CharactersTable.getInstance().getPc(name);
    }

    /**
     * 取得缓存列表(全部).
     * 
     * @return 列表中的所有元素
     */
    public static final Map<String, L1PcInstance> get() {
        return CharactersTable.getInstance().get();
    }

    /**
     * 取得缓存列表(全部).
     * 
     * @return 列表中的所有元素
     */
    public static final Collection<L1PcInstance> getList() {
        return CharactersTable.getInstance().getList();
    }

    /**
     * 计算物理防御(敏捷加成).
     * 
     * @param pc
     *            - 角色
     */
    public static int calcAc(final L1PcInstance pc) {
        return CalcStat.calcAc(pc);
    }

    /**
     * 取得与该角色职业对应的初始属性：力量值.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始属性：力量值
     */
    public static final int getOriginalStr(final L1PcInstance pc) {
        return Original.getOriginalStr(pc);
    }

    /**
     * 取得与该角色职业对应的初始属性：敏捷值.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始属性：敏捷值
     */
    public static final int getOriginalDex(final L1PcInstance pc) {
        return Original.getOriginalDex(pc);
    }

    /**
     * 取得与该角色职业对应的初始属性：体质值.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始属性：体质值
     */
    public static final int getOriginalCon(final L1PcInstance pc) {
        return Original.getOriginalCon(pc);
    }

    /**
     * 取得与该角色职业对应的初始属性：精神值.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始属性：精神值
     */
    public static final int getOriginalWis(final L1PcInstance pc) {
        return Original.getOriginalWis(pc);
    }

    /**
     * 取得与该角色职业对应的初始属性：智力值.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始属性：智力值
     */
    public static final int getOriginalInt(final L1PcInstance pc) {
        return Original.getOriginalInt(pc);
    }

    /**
     * 取得与该角色职业对应的初始属性：魅力值.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始属性：魅力值
     */
    public static final int getOriginalCha(final L1PcInstance pc) {
        return Original.getOriginalCha(pc);
    }

    /**
     * 取得与该角色职业对应的初始可分配点数.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的可分配点数
     */
    public static final int getOriginalCount(final L1PcInstance pc) {
        return Original.getOriginalCount(pc);
    }

    /**
     * 取得与该角色职业对应的外形编号.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的外形编号
     */
    public static final int getClassId(final L1PcInstance pc) {
        return Original.getClassId(pc);
    }

    /**
     * 取得与该角色职业对应的出生坐标.
     * 
     * @param pc
     *            - 角色
     * @return 数组[0：x坐标、1：y坐标、2：地图编号]
     */
    public static final int[] getLocation(final L1PcInstance pc) {
        return Original.getLocation(pc);
    }

    /**
     * 取得各职业的初始血量.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始血量值
     */
    public static final int getOriginalHp(final L1PcInstance pc) {
        return Original.getOriginalHp(pc);
    }

    /**
     * 取得各职业的初始魔量.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的初始魔量值
     */
    public static final int getOriginalMp(final L1PcInstance pc) {
        return Original.getOriginalMp(pc);
    }

    /**
     * 取得角色为等待删除状态时的职业编号.
     * 
     * @param pc
     *            - 角色
     * @return 与该职业对应的编号
     */
    public static final int getWaitDeleteId(final L1PcInstance pc) {
        return Other.getWaitDeleteId(pc);
    }

    /**
     * 取得各职业的初始物理防御值(敏捷加成).
     * 
     * @param pc
     *            - 角色
     * @return 与该职业的‘初始敏捷加点’对应的‘物理防御值’
     */
    public static final int getOriginalAc(final L1PcInstance pc) {
        return Original.getOriginalAc(pc);
    }

    /**
     * 角色离开游戏的相关处理.
     * 
     * @param pc
     *            - 要处理的在线角色
     */
    public static final void QuitGame(final L1PcInstance pc) {
        QuitGame.execute(pc);
    }

    // --------------------------------- 在线相关 ---------------------------------
    /**
     * 将角色‘加入’在线列表.
     * 
     * @param name
     *            - 要加入的角色名称
     * @return 如果成功加入则返回true
     */
    public static final boolean addOnline(final String name) {
        return OnlineList.getInstance().add(name);
    }

    /**
     * 将角色加入在线列表.
     * 
     * @param pc
     *            - L1PcInstance对象
     * @return 如果成功加入则返回true
     */
    public static final boolean addOnline(final L1PcInstance pc) {
        return OnlineList.getInstance().add(pc);
    }

    /**
     * 检查是否在线(根据角色名).
     * 
     * @param name
     *            - 要检查的角色名称
     * @return 如果在线则返回true
     */
    public static final boolean isOnline(final String name) {
        return OnlineList.getInstance().isOnline(name);
    }

    /**
     * 检查是否在线.
     * 
     * @param pc
     *            - 要检查的角色
     * @return 如果在线则返回true
     */
    public static final boolean isOnline(final L1PcInstance pc) {
        return OnlineList.getInstance().isOnline(pc);
    }

    /**
     * 根据角色名取得在线角色数据.
     * 
     * @param name
     *            - 角色名
     * @return L1PcInstance对象(如果找不到则返回null)
     */
    public static final L1PcInstance getPcOnline(final String name) {
        return OnlineList.getInstance().getPcOnline(name);
    }

    /**
     * 将角色‘移出’在线列表.
     * 
     * @param name
     *            - 要移出的角色名称
     * @return 如果成功移出则返回true
     */
    public static final boolean remove(final String name) {
        return OnlineList.getInstance().remove(name);
    }

    /**
     * 将角色‘移出’在线列表.
     * 
     * @param pc
     *            - 要移出的角色
     * @return 如果成功移出则返回true
     */
    public static final boolean remove(final L1PcInstance pc) {
        return OnlineList.getInstance().remove(pc);
    }

    /**
     * 取得在线角色数量.
     * 
     * @return 总数量
     */
    public static final int getCountOnline() {
        return OnlineList.getInstance().getCount();
    }

    /**
     * 取得在线列表.
     * 
     * @return 列表
     */
    public static final List<String> getListOnline() {
        return OnlineList.getInstance().getList();
    }

    /**
     * 取得最高等级.
     * 
     * @return 最高等级
     */
    public static final int getMaxLevel() {
        return ExpTable.getInstance().getMaxLevel();
    }

    /**
     * 取得最高经验值.
     * 
     * @return 最高经验值
     */
    public static final long getMaxExp() {
        return ExpTable.getInstance().getMaxExp();
    }
}
